package com.lineage.william;

import com.add.SetBoss;
import com.lineage.DatabaseFactory;
import com.lineage.server.IdFactory;
import com.lineage.server.datatables.NpcTable;
import com.lineage.server.model.Instance.L1MonsterInstance;
import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.model.L1Inventory;
import com.lineage.server.model.L1Object;
import com.lineage.server.model.L1Teleport;
import com.lineage.server.serverpackets.S_BlueMessage;
import com.lineage.server.serverpackets.S_ServerMessage;
import com.lineage.server.serverpackets.S_SystemMessage;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.thread.GeneralThreadPool;
import com.lineage.server.utils.SQLUtil;
import com.lineage.server.world.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;

public class BossRoom {
  public static final int STATUS_NONE = 0;
  
  public static final int STATUS_READY = 1;
  
  public static final int STATUS_PLAYING = 2;
  
  public static final int STATUS_CLEANING = 4;
  
  private static final int _minPlayer = SetBoss._82;
  
  private static final int _maxPlayer = SetBoss._83;
  
  private static final int _readytime = SetBoss._84 * 1000;
  
  private static final int _cleartime = SetBoss._85 * 1000;
  
  private static final int _bossId1 = SetBoss._88;
  
  private static final int _bossId3 = SetBoss._90;
  
  private static final int _bossId5 = SetBoss._92;
  
  private static final int _bossId7 = SetBoss._94;
  
  private static final int _bossId9 = SetBoss._96;
  
  private static final int _bossId11 = SetBoss._98;
  
  private static final int _bossId13 = SetBoss._100;
  
  private static final int _bossId15 = SetBoss._102;
  
  private static final int _bossId17 = SetBoss._104;
  
  private static final int _bossId19 = SetBoss._106;
  
  private static BossRoom _instance;
  
  private final ArrayList<L1PcInstance> _members = new ArrayList<>();
  
  private int _BossRoomStatus = 0;
  
  public static BossRoom getInstance() {
    if (_instance == null)
      _instance = new BossRoom(); 
    return _instance;
  }
  
  public String enterBossRoom(L1PcInstance pc) {
    if (getInstance().getBossRoomStatus() == 4) {
      pc.sendPackets((ServerBasePacket)new S_SystemMessage("目前挑战馆清洁重置中请稍后再来。"));
      return "";
    } 
    if (getInstance().getBossRoomStatus() == 2 && !isMember(pc)) {
      pc.sendPackets((ServerBasePacket)new S_ServerMessage(1182));
      return "";
    } 
    if (getMembersCount() >= _maxPlayer && !isMember(pc)) {
      pc.sendPackets((ServerBasePacket)new S_SystemMessage("挑战馆参与人数已满无法进入。"));
      return "";
    } 
    if (!isMember(pc) && SetBoss._86 > 0 && SetBoss._87 > 0 && 
      !pc.getInventory().checkItem(SetBoss._86, SetBoss._87)) {
      pc.sendPackets((ServerBasePacket)new S_SystemMessage("您的参赛所需道具数量或人数不足"));
      return "";
    } 
    if (pc.isInParty()) {
      if (getBossRoomStatus() != 1 || getBossRoomStatus() != 2)
        pc.getInventory().consumeItem(SetBoss._86, SetBoss._87); 
      ConcurrentHashMap<Integer, L1PcInstance> pcs = pc.getParty().partyUsers();
      Iterator<L1PcInstance> iter = pcs.values().iterator();
      while (iter.hasNext()) {
        L1PcInstance pcc = iter.next();
        if (pcc.getMapId() != SetBoss._108) {
          L1Teleport.teleport(pcc, SetBoss._109, SetBoss._110, (short)SetBoss._108, pcc.getHeading(), true);
          addMember(pcc);
        } 
      } 
    } else {
      if (getBossRoomStatus() != 1 || getBossRoomStatus() != 2)
        pc.getInventory().consumeItem(SetBoss._86, SetBoss._87); 
      L1Teleport.teleport(pc, SetBoss._109, SetBoss._110, (short)SetBoss._108, pc.getHeading(), true);
      addMember(pc);
    } 
    return "";
  }
  
  private void addMember(L1PcInstance pc) {
    if (!this._members.contains(pc))
      this._members.add(pc); 
    if (getMembersCount() == 1 && getBossRoomStatus() == 0)
      GeneralThreadPool.get().execute(new runBossRoom()); 
  }
  
  private boolean checkPlayerCount() {
    if (getMembersCount() < _minPlayer) {
      setBossRoomStatus(4);
      sendMessage("人数不足 " + _minPlayer + " 人，所以强制关闭游戏");
      L1PcInstance[] membersArray;
      int length = (membersArray = getMembersArray()).length;
      for (int i = 0;i < length; i++) {
        L1PcInstance pc = membersArray[i];
        L1Teleport.teleport(pc, SetBoss._112, SetBoss._113, (short)SetBoss._111, pc.getHeading(), true);
      } 
      clearMembers();
      endBossRoom();
      return false;
    } 
    return true;
  }
  
  private void endBossRoom() {
    setBossRoomStatus(4);
    sendMessage("挑战馆游戏结束，请下次再来");
    L1PcInstance[] membersArray;
    int length = (membersArray = getMembersArray()).length;
    for (int i = 0;i < length; i++) {
      L1PcInstance pc = membersArray[i];
      L1Teleport.teleport(pc, SetBoss._112, SetBoss._113, (short)SetBoss._111, pc.getHeading(), true);
    } 
    clearMembers();
    clearColosseum();
  }
  
  private void clearColosseum() {
    Iterator<L1Object> iterator = World.get().getVisibleObjects(SetBoss._108).values().iterator();
    while (iterator.hasNext()) {
      Object obj = iterator.next();
      if (obj instanceof L1MonsterInstance) {
        L1MonsterInstance mob = (L1MonsterInstance)obj;
        if (mob.isDead())
          continue; 
        mob.setDead(true);
        mob.setStatus(8);
        mob.setCurrentHpDirect(0);
        mob.deleteMe();
        continue;
      } 
      if (!(obj instanceof L1Inventory))
        continue; 
      L1Inventory inventory = (L1Inventory)obj;
      inventory.clearItems();
    } 
  }
  
  private void spawnBoss(int npcid, String msg1, String msg2) {
    spawn(npcid);
  }
  
  private void spawn(int npcid) {
    try {
      L1NpcInstance npc = NpcTable.get().newNpcInstance(npcid);
      npc.setId(IdFactory.get().nextId());
      npc.setMap((short)SetBoss._108);
      npc.setX(SetBoss._109);
      npc.setY(SetBoss._110);
      Thread.sleep(1L);
      npc.setHomeX(npc.getX());
      npc.setHomeY(npc.getY());
      npc.setHeading(4);
      World.get().storeObject((L1Object)npc);
      World.get().addVisibleObject((L1Object)npc);
      npc.turnOnOffLight();
      npc.startChat(0);
    } catch (Exception exception) {}
  }
  
  private String getBossName(int npcId) {
    String BossName = null;
    Connection con = null;
    PreparedStatement pstm = null;
    ResultSet rs = null;
    try {
      con = DatabaseFactory.get().getConnection();
      pstm = con.prepareStatement("select name from npc where npcid = ?");
      pstm.setInt(1, npcId);
      rs = pstm.executeQuery();
      if (rs.next())
        BossName = rs.getString("name"); 
    } catch (SQLException sQLException) {
    
    } finally {
      SQLUtil.close(rs);
      SQLUtil.close(pstm);
      SQLUtil.close(con);
    } 
    return BossName;
  }
  
  private void sendMessage(String msg) {
    L1PcInstance[] membersArray;
    int length = (membersArray = getMembersArray()).length;
    int i = 0;
    while (i < length) {
      L1PcInstance pc = membersArray[i];
      if (pc.getMapId() == SetBoss._108) {
        pc.sendPackets((ServerBasePacket)new S_BlueMessage(166, "\\f3" + msg));
        pc.sendPackets((ServerBasePacket)new S_SystemMessage("\\f3" + msg));
      } 
      i++;
    } 
  }
  
  public void removeMember(L1PcInstance pc) {
    this._members.remove(pc);
  }
  
  private int getBossRoomStatus() {
    return this._BossRoomStatus;
  }
  
  private void setBossRoomStatus(int i) {
    this._BossRoomStatus = i;
  }
  
  private void clearMembers() {
    this._members.clear();
  }
  
  public boolean isMember(L1PcInstance pc) {
    return this._members.contains(pc);
  }
  
  public L1PcInstance[] getMembersArray() {
    return this._members.<L1PcInstance>toArray(new L1PcInstance[this._members.size()]);
  }
  
  private int getMembersCount() {
    return this._members.size();
  }
  
  private class runBossRoom implements Runnable {
    private runBossRoom() {}
    
    public void run() {
      try {
        BossRoom.this.setBossRoomStatus(1);
        BossRoom.this.sendMessage(String.valueOf(String.valueOf(SetBoss._84)) + "秒后开始进行关卡挑战");
        Thread.sleep(BossRoom._readytime);
        BossRoom.this.sendMessage("倒数10秒");
        Thread.sleep(5000L);
        BossRoom.this.sendMessage("倒数5秒");
        Thread.sleep(1000L);
        BossRoom.this.sendMessage("4秒");
        Thread.sleep(1000L);
        BossRoom.this.sendMessage("3秒");
        Thread.sleep(1000L);
        BossRoom.this.sendMessage("2秒");
        Thread.sleep(1000L);
        BossRoom.this.sendMessage("1秒");
        Thread.sleep(1000L);
        if (BossRoom.this.checkPlayerCount()) {
          BossRoom.this.setBossRoomStatus(2);
          BossRoom.this.spawnBoss(BossRoom._bossId1, "1", "2");
          BossRoom.this.sendMessage("第 2关 [挑战Boss]将在 " + SetBoss._89 + "秒后出现");
          Thread.sleep((SetBoss._89 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId3, "2", "3");
          BossRoom.this.sendMessage("第 3关 [挑战Boss]将在 " + SetBoss._91 + "秒后出现");
          Thread.sleep((SetBoss._91 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId5, "3", "4");
          BossRoom.this.sendMessage("第 4关 [挑战Boss]将在 " + SetBoss._93 + "秒后出现");
          Thread.sleep((SetBoss._93 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId7, "4", "5");
          BossRoom.this.sendMessage("第 5关 [挑战Boss]将在 " + SetBoss._95 + "秒后出现");
          Thread.sleep((SetBoss._95 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId9, "5", "6");
          BossRoom.this.sendMessage("第6关 [挑战Boss]将在 " + SetBoss._97 + "秒后出现");
          Thread.sleep((SetBoss._97 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId11, "6", "7");
          BossRoom.this.sendMessage("第 7关 [挑战Boss]将在 " + SetBoss._99 + "秒后出现");
          Thread.sleep((SetBoss._99 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId13, "7", "8");
          BossRoom.this.sendMessage("第 8关 [挑战Boss]将在 " + SetBoss._101 + "秒后出现");
          Thread.sleep((SetBoss._101 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId15, "8", "9");
          BossRoom.this.sendMessage("第 9关 [挑战Boss]将在 " + SetBoss._103 + "秒后出现");
          Thread.sleep((SetBoss._103 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId17, "9", "10");
          BossRoom.this.sendMessage("第 10关 [挑战Boss]将在 " + SetBoss._105 + "秒后出现");
          Thread.sleep((SetBoss._105 * 1000));
          BossRoom.this.spawnBoss(BossRoom._bossId19, "10", null);
          BossRoom.this.sendMessage("[最终挑战Boss]将在 " + SetBoss._107 + "秒关闭此道馆");
          Thread.sleep((SetBoss._107 * 1000));
          BossRoom.this.endBossRoom();
        } 
        Thread.sleep(BossRoom._cleartime);
        BossRoom.this.setBossRoomStatus(0);
      } catch (InterruptedException e) {
        e.printStackTrace();
      } 
    }
  }
}
